package logic

import (
	"context"
	"crypto/rand"
	"errors"
	"fmt"
	"godco/internal/utils"
	"math/big"
	"strconv"
	"strings"
	"time"

	u "godco/internal/model/users"
	"godco/internal/svc"
	"godco/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type UserSignLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUserSignLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserSignLogic {
	return &UserSignLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UserSignLogic) UserSign(req *types.SignRequest) (resp *types.SignResp, err error) {
	// todo: add your logic here and delete this line
	//先验证验证码是否正确
	key := req.Email
	value, err := l.svcCtx.RedisClient.Get(key)
	if err != nil {
		return nil, err
	}
	if value != req.VerifyCode {
		return nil, errors.New("验证码错误")
	}
	l.svcCtx.RedisClient.Del(key)

	_, err = l.svcCtx.AuthModel.FindOneByInstallID(l.ctx, strconv.FormatInt(req.Aid, 10))
	if err == u.ErrNotFound {
		return nil, errors.New("请获取正确的签署地址")
	}

	_, err = l.svcCtx.UserModel.FindOneByEmailAndInstallationId(l.ctx, req.Email, req.Aid)
	if err == u.ErrNotFound {
		data := u.User{Name: req.Name, Email: req.Email, State: "yes", InstallationId: req.Aid}
		err = l.svcCtx.UserModel.Insert(l.ctx, &data)
		if err != nil {
			resp = &types.SignResp{
				Code:    403,
				Message: err.Error(),
			}
			return resp, nil
		}
	}
	resp = &types.SignResp{
		Code:    0,
		Message: "success",
	}
	return resp, nil
}

func (l *UserSignLogic) CaptureEmailCode(req *types.EmailCodRequest) (resp *types.EmailCodeResp, err error) {
	_, err = l.svcCtx.UserModel.FindOneByEmailAndInstallationId(l.ctx, req.Email, req.Aid)
	if err != u.ErrNotFound {
		return nil, errors.New("该邮箱已签署")
	}
	key := req.Email
	keyBool, err := l.svcCtx.RedisClient.Exists(key)
	if err != nil {
		return nil, err
	}
	if keyBool {
		return nil, errors.New("操作频繁")
	}
	//获取当前时间戳的毫秒数
	timestamp := time.Now().UnixMilli()
	// 结合时间戳和随机数生成唯一种子
	// 这里将时间戳作为随机数生成的一部分，确保每次生成的验证码和时间相关
	seed := fmt.Sprintf("%d", timestamp)

	// 生成随机数
	var code string
	for i := 0; i < 6; i++ {
		// 生成 0 到 9 之间的随机数
		n, _ := rand.Int(rand.Reader, big.NewInt(10))
		// 将随机数添加到验证码中
		code += fmt.Sprintf("%d", n.Int64())
	}

	// 可以根据需要对验证码进行哈希处理或其他操作，进一步保证唯一性
	// 这里简单地将时间戳的后几位和随机验证码拼接
	uniqueCode := fmt.Sprintf("%s%s", seed[len(seed)-3:], code)
	uniqueCode = uniqueCode[len(uniqueCode)-6:]
	resp = &types.EmailCodeResp{
		Code:    0,
		Message: "success",
	}
	err = l.svcCtx.RedisClient.Setex(key, code, 600)
	if err != nil {
		return nil, err
	}
	emailTemplateContent, _ := utils.ReadTemplateFile("email_verify_code_template.txt")
	if emailTemplateContent == "" {
		emailTemplateContent = l.svcCtx.Config.EConf.EmailCodeInfo
	}
	l.Debug(uniqueCode)
	emailContent := strings.Replace(emailTemplateContent, "{verifyCode}", uniqueCode, -1)

	err = utils.SendEmail(l.svcCtx.Config.EConf.From, l.svcCtx.Config.EConf.Pwd, l.svcCtx.Config.EConf.Server, req.Email, "DCO签名验证码", emailContent, "text/html")
	if err != nil {
		l.svcCtx.RedisClient.Del(key)
		return nil, err
	}
	return resp, nil
}
